grammar Cymbol;

/*
    在本节中，不支持前向定义，然后也不支持方法返回结构体类型
*/

compilationUnit
    :   (structDeclaration | methodDeclaration | varDeclaration)+
    ;

structDeclaration
	:	'struct' ID '{' structMember+ '}' ';'
	;
	
structMember
	:	type ID ';'
	|	structDeclaration
	;

// START: method
methodDeclaration
    :   type ID '(' formalParameters? ')' block
    ;
// END: method

formalParameters
    :   type ID (',' type ID)*
    ;

type:   'float'
    |   'int'
    |	'void'
    |   ID  // 主要用于 struct
    ;

// START: block
block
    :   '{' statement* '}'
    ;
// END: block

// START: var
varDeclaration
    :   type ID ('=' expression)? ';'
    ;
// END: var

statement
    :   block
    |   structDeclaration
    |	varDeclaration
    |   RETURN expression? ';'
    |   postfixExpression ('=' expression)? ';' // handles function calls like f(i);
    ;

expressionList
    :   expression (',' expression)*
    |
    ;

expression
    :   addExpression
    ;

addExpression
	:	postfixExpression ('+' postfixExpression)*
	;

postfixExpression
    :   ID '(' expressionList ')'   #callExpression         // 方法调用表达式
    |   ID ('.' ID)+                #memeberExpression      // 成员访问表达式
    |   ID                          #referenceExpression    // 变量引用表达式
    |   INT                         #literalExpression      // 字面量表达式
    ;

// LEXER RULES

RETURN 
    : 'return'
    ;

ID  :   LETTER (LETTER | '0'..'9')*
    ;

fragment
LETTER  :   ('a'..'z' | 'A'..'Z')
    ;

INT :   '0'..'9'+
    ;

WS  :   (' '|'\r'|'\t'|'\n') -> skip
    ;

SL_COMMENT
    :   '//' ~('\r'|'\n')* '\r'? '\n' -> skip
    ;
